﻿using Common.Framework.Core.Cache;
using Common.Framework.Core.Common;
using Common.Framework.Core.Const;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Common.Framework.Core.Middleware
{
    /// <summary>
    /// 该中间件必须放在 UseAuthentication 和 UseAuthorization 之后
    /// </summary>
    public class AuthenticationCustomMiddleware
    {
        private readonly RequestDelegate _next;
        //private readonly ILogger _logger;
        //public CustomAuthenticationMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)

        /// <summary>
        /// 
        /// </summary>
        /// <param name="next"></param>
        public AuthenticationCustomMiddleware(RequestDelegate next)
        {
            _next = next;
            //_logger = loggerFactory.CreateLogger<CustomAuthenticationMiddleware>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public async Task InvokeAsync(HttpContext context)
        {
            //_logger.LogInformation($"Client Ip:{httpContext.Connection.RemoteIpAddress.ToString()}");
            //......

            // Call the next delegate/middleware in the pipeline

            //从缓存中获取用户权限信息

            //如果在token中没有找到用户的角色id,则认为这个请求不需要控制权限.可以直接放行.
            //前提条件是 该中间件必须放在 UseAuthentication 和 UseAuthorization 之后
            var roleIds = context.User.Claims.Where(s => s.Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
            bool isAuth = false; //是否有权通过true:有权,false:没权
            if (roleIds != null && roleIds.Any())
            {
                //当前请求的url
                string currentPath = context.Request.Path;
                var authMsterRole = roleIds.Count(s => s.Value == CommonConst.AuthMasterRoleId);
                if (authMsterRole > 0)
                {
                    isAuth = true;
                }
                else
                {
                    foreach (var roleId in roleIds)
                    {
                        //从缓存中根据角色id获取权限,然后和path进行比对,
                        var roleMenus = MemoryCache.Instance.Get<List<string>>($"{CommonConst.Cache_Auth}{roleId.Value}");

                        if (roleMenus == null || !roleMenus.Any())
                        {
                            //如果没有从缓存中找到权限,也不放行.
                            //所以需要要求权限缓存的时间要大于token的有效期
                            //可以设置权限永不过期,当对角色进行权限修改时更新权限
                            break;
                        }
                        var roleMenuCount = roleMenus.Count(s => currentPath.ToLower().Contains(s));
                        if (roleMenuCount > 0)
                        {
                            //没有权限,不放行
                            isAuth = true;
                            break;
                        }
                    }
                }
            }
            else
            {
                isAuth = true;
            }

            if (isAuth)
            {
                await _next(context);
            }
            else
            {
                context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                await context.Response.WriteAsJsonAsync(new ServiceResult { Code = StatusCodes.Status401Unauthorized, Msg = "无权访问" });
            }
        }
    }

    /// <summary>
    /// Extension method used to add the middleware to the HTTP request pipeline.
    /// </summary>
    public static class AuthenticationCustomMiddlewareExtensions
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="builder"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseAuthenticationCustom(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<AuthenticationCustomMiddleware>();
        }
    }
}
